<html>
  <head>
    <link rel="stylesheet" type="text/css" title="Default Style" href="../../style/tree/compat/style.css" media="screen" />

    <style>
      HTML,
      BODY
      {
        font-size: small;
        font-family: Tahoma, Verdana, Arial, sans-serif;
        height: 100%;
        overflow: hidden;
        margin: 0;
        padding: 0;
      }
      BODY
      {
        padding: 0px;
      }

      .Basis-TreeNode-Title.highlight
      {
        background: gold;
          -webkit-transition: background-color .05s;
        transition: background-color .05s;
      }
      .Basis-TreeNode-Title
      {
          -webkit-transition: background-color 2s .6s;
        transition: background-color 1s .5s;
      }
      .modified
      {
        border-color: red !important;
      }
    </style>

    <script>
      document.write('<script src="//' + location.host + ':8222/socket.io/socket.io.js"></sc' + 'ript>');
    </script>
    <script src="../../basis-all.js"></script>
    <script>
      var postMessageSupported = window.postMessage && top !== this;
      console.log(postMessageSupported);

      var FSFile = new basis.entity.EntityType({
        fields: {
          filename: basis.entity.StringId,
          type: String,
          lastUpdate: Date.fromISOString,
          content: String
        }
      });

      FSFile.entityType.entityClass.extend({
        event_subscribersChanged: function(){
          if (this.subscriberCount)
          {
            socket.emit('watchFileContent', this.data.filename);
          }
          else
          {
            socket.emit('unwatchFileContent', this.data.filename);
          }
        },
        save: function(){
          if (this.modified)
          {
            socket.emit('saveFile', this.data.filename, this.data.content);
          }
        }
      });

      var filesByFolder = new basis.data.dataset.Split({
        source: FSFile.all,
        rule: function(object){
          var path = object.data.filename.split("/");
          path.pop();
          return path.join('/');
        }
      });

      basis.dom.event.onLoad(function(){
        var childFactory = function(cfg){
          var childClass = cfg.delegate.data.type == 'dir' ? FolderNode : FileNode;
          return new childClass(cfg);
        };

        var classList = basis.cssom.classList;
        var updatedNodes = new basis.data.Dataset({
          handler: {
            datasetChanged: function(dataset, delta){
              var array;

              if (array = delta.inserted)
                for (var i = 0; i < array.length; i++)
                  classList(array[i].tmpl.content).add('highlight');

              if (array = delta.deleted)
                for (var i = 0; i < array.length; i++)
                  classList(array[i].tmpl.content).remove('highlight');

              if (this.itemCount && !this.timer)
                this.timer = setTimeout(function(){
                  this.timer = 0;
                  this.clear();
                }.bind(this), 50);
            }
          }
        });

        var FileNode = basis.ui.tree.Node.subclass({
          binding: {
            title: 'data:filename.split("/").slice(-1)'
          },

          event_update: function(object, delta){
            basis.ui.tree.Node.prototype.event_update.call(this, object, delta);
            updatedNodes.add([this]);
          }
        });
        var FolderNode = basis.ui.tree.Folder.subclass({
          binding: {
            title: 'data:filename.split("/").slice(-1)'
          },

          /*event_update: function(object, delta){
            basis.ui.tree.Node.prototype.event_update.call(this, object, delta);
            updatedNodes.add([this]);
          },*/

          childFactory: childFactory,
          sorting: 'data.filename',
          grouping: {
            groupGetter: 'data.type',
            sorting: 'data.id == "file"',
            childClass: {
              template: '<div/>'
            }
          },

          init: function(config){
            basis.ui.tree.Folder.prototype.init.call(this, config);
            this.setDataSource(filesByFolder.getSubset(this.data.filename, true));
          }
        });

        var fileTree = new basis.ui.tree.Tree({
          container: document.body,
          dataSource: filesByFolder.getSubset('../templater', true),
          childFactory: childFactory,
          sorting: 'data.filename',
          grouping: {
            groupGetter: 'data.type',
            sorting: 'data.id == "file"',
            childClass: {
              template: '<div/>'
            }
          },
          selection: {
            handler: {
              datasetChanged: function(dataset, delta){
                var selected = this.pick();
                if (selected)
                {
                  if (postMessageSupported)
                    top.postMessage(selected.data, '*');
                }
                fileView.setDelegate(selected)
              }
            }
          }
        });

        fileView = new basis.ui.Node({
          container: document.body,
          active: true,

          template: 
            '<div style="border: 1px solid green" class="{modified}">' +
              '<div>{filename}</div>' +
              '<textarea{textarea} disabled="{disabled}" event-keyup="update" event-input="update" event-changed="update">' +
                //'{fileContent}' +
              '</textarea>' +
            '</div>',

          binding: {
            filename: 'data:',
            modified: {
              events: 'targetChanged',
              getter: function(node){
                return node.target && node.target.modified ? 'modified' : '';
              }
            }
          },

          action: {
            update: function(){
              if (this.target)
              {
                this.target.update({ content: this.tmpl.textarea.value }, true);
              }
            }
          },

          listen: {
            target: {
              rollbackUpdate: function(){
                this.updateBind('modified');
              }
            }
          },

          handler: {
            update: function(object, delta){
              if ('content' in delta)
                this.tmpl.textarea.value = this.data.content;
            },
            targetChanged: function(){
              if (this.target)
                this.enable();
              else
              {
                this.update({ content: '' });
                this.disable();
              }
            }
          }
        });
        new basis.ui.button.ButtonPanel({
          container: document.body,
          childNodes: [
            {
              delegate: fileView,
              caption: 'rollback',
              click: function(){
                if (this.target)
                  this.target.rollback();
              }
            },
            {
              delegate: fileView,
              caption: 'save',
              click: function(){
                if (this.target)
                  this.target.save();
              }
            }
          ]
        })
      });
    </script>
    <script>
      if (typeof io != 'undefined')
      {
        var socket = io.connect(':8222');

        socket.on('connect', function(){
          if (postMessageSupported)
          {
            top.postMessage('fileObserverLoaded', '*');
          }
        });

        socket.on('newFile', function (data) {
          console.log('new file', data);

          FSFile(data);
        });
        socket.on('updateFile', function (data) {
          console.log('file updated', data);

          FSFile(data);
        });
        socket.on('deleteFile', function (data) {
          console.log('file deleted', data);

          var file = FSFile.get(data);
          if (file)
            file.destroy();
        });
        socket.on('fileSaved', function (data) {
          console.log('file saved', data);
        });
        socket.on('filelist', function (data) {
          console.log('filelist', data);
          FSFile.all.sync(data);
        });
        socket.on('error', function (data) {
          console.log('error:', data.operation, data.message);
        });
      }
    </script>
  </head>
  <body>
  </body>
</html>